/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022.  All rights reserved.2023.
 */
package service

import (
	"prim-server/config"
	"prim-server/dao"
	"prim-server/logger"
	"prim-server/model"
	"prim-server/util"
	"prim-server/util/toolcbc"
	"strings"

	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

func GetCloudUserAll(userId []string) ([]*model.CloudUser, error) {
	cloudUsers, err := dao.GetCloudUserDao().GetCloudUserInfo(userId)
	if err != nil {
		logger.Error("get user error: %v, userId: %s", err.Error(), userId)
		return nil, errors.New("查找用户出错")
	}
	// 查询数据库出错
	if len(cloudUsers) == 0 {
		return nil, nil
	}
	return cloudUsers, nil
}
func GetCloudUserOne(userId string) (*model.CloudUser, error) {
	cloudUsers, err := GetCloudUserAll([]string{userId})
	if err != nil {
		return nil, err
	}
	if len(cloudUsers) == 0 {
		return nil, nil
	}
	cloudUser := cloudUsers[0]
	return cloudUser, nil
}
func CreateCloudUser(userId string, userName string) (err error) {
	cloudUsers, err := dao.GetCloudUserDao().GetCloudUserInfo([]string{userId})
	if err != nil {
		logger.Error(err.Error())
		return errors.New("查找用户出错")
	}
	// 查询数据库出错
	if len(cloudUsers) > 0 {
		return errors.New("用户已存在")
	}
	cloudUser := new(model.CloudUser)
	cloudId, cloudName, cloudPassword, err := toolcbc.CreatCloudUser(cast.ToString(userId), userName)
	if len(cloudId) == 0 {
		return nil
	}
	if err != nil {
		logger.Error(err.Error())
		return errors.New("云上用户创建失败")
	}
	cloudUser.UserId = userId
	cloudUser.CloudId = cloudId
	cloudUser.CloudName = cloudName
	cloudUser.CloudPassword = cloudPassword
	err = dao.GetCloudUserDao().SaveCloudUserInfo(cloudUser)
	if err != nil {
		logger.Error("save cloud user error: %v, userId: %s", err.Error(), userId)
		return errors.New("云上用户创建失败")
	}
	return nil
}

// 提交实名认证申请--个人身份证实名认证限定
func ApplyForRealNameAuthenticationPerson(userId, verificationName, verificationId string) error {
	user, err := GetUserOneWithUserId(userId)
	if err != nil {
		logger.Error("get user error: %v, userId: %s", err.Error(), userId)
		return errors.New("查找用户出错")
	}
	if user.Authenticated {
		return errors.New("用户已实名")
	}
	cloudUser, err := GetCloudUserOne(userId)
	//查找云上用户,错误已处理
	if err != nil {
		return err
	}
	//检查所需照片是否存在--错误已处理
	filePath, err := GetIDCardFileForPerson(userId)
	if err != nil {
		logger.Error("get id file error: %v, userId: %s", err.Error(), userId)
		return err
	}
	//检查是否正在审核或审核通过--错误已处理
	_, reviewResult, err := CheckRealNameAuthenticationPerson(userId)
	if err != nil {
		return err
	} else {
		if reviewResult != nil {
			if *reviewResult == toolcbc.AuthenticationPassed {
				return errors.New("已审核通过")
			}
			if *reviewResult == toolcbc.AuthenticationUnderReview {
				return errors.New("审核中")
			}
		}
	}
	identifyType := cast.ToInt32(toolcbc.IdentifyTypeOfIDCard)
	verifiedType := cast.ToInt32(toolcbc.VerifiedTypeOfIDCard)

	xAccountType := config.GetConfig().BSSConfig.XAccountType
	request := toolcbc.BuildApplyIndividualRealnameAuthsReq(
		cloudUser.CloudId, xAccountType, verificationName,
		verificationId, identifyType, &verifiedType, filePath)
	reponse, err := toolcbc.RealNameAuthenticationPerson(*request)
	if err != nil {
		logger.Error("apply for authentication error: %v,userId:%s", err.Error(), userId)
		return errors.New("提起实名认证失败")
	} else {
		if *reponse.IsReview == 1 {
			return errors.New("请等待人工审核,大概1-3个工作日")
		}
	}
	return nil
}

// 检查用户实名认证状态--个人身份证实名认证限定
func CheckRealNameAuthenticationPerson(userId string) (string, *int32, error) {
	user, err := GetUserOneWithUserId(userId)
	if err != nil {
		logger.Error("get user error: %v, userId: %s", err.Error(), userId)
		return "", nil, errors.New("查找用户出错")
	}
	if user.Authenticated {
		return "", nil, errors.New("用户已实名")
	}
	cloudUser, err := GetCloudUserOne(userId)
	//查找云上用户,错误已处理
	if err != nil {
		return "", nil, err
	}
	//检查用户实名状态--api
	response, err := toolcbc.GetRealNameAuthentication(cloudUser.CloudId)
	if err != nil {
		logger.Error("get authentication error: %v, userId: %v", err.Error(), userId)
		return "", nil, errors.New("查询实名认证结果信息失败")
	} else {
		if response.ReviewResult == nil {
			return "未上传相关文件", nil, nil
		}
	}
	status := ""
	if *response.ReviewResult == toolcbc.AuthenticationUnderReview {
		status = "审核中"
	} else if *response.ReviewResult == toolcbc.AuthenticationPassed {
		status = "审核通过"
	} else if *response.ReviewResult == toolcbc.AuthenticationReject {
		status = "审核不通过\n审核意见如下:" + *response.Opinion
	}
	return status, response.ReviewResult, nil
}

// 获取已经上传的身份证材料路径(含桶名)----个人身份证实名认证限定
func GetIDCardFileForPerson(userId string) ([]string, error) {
	prefix := util.BuildPrefixForIDCard(userId)
	contens, err := util.ListBuckObjectForIDCard(userId, prefix)
	if err != nil {
		logger.Error("get id file error: %v, userId: %s", err.Error(), userId)
		return nil, errors.New("查询上传材料失败")
	}
	if len(contens) == 0 {
		return nil, errors.New("未上传相关材料")
	}
	IDCardFiles := make(map[int]int)
	errStr := ""
	var finalPath []string
	for _, val := range contens {
		IDCardParts := strings.Split(val, "/")
		part := cast.ToInt(IDCardParts[len(IDCardParts)-1])
		IDCardFiles[part] = 1

		finalPart := IDCardParts[len(IDCardParts)-2] + "/" + IDCardParts[len(IDCardParts)-1]
		finalPath = append(finalPath, finalPart)
	}
	if _, ok := UploadIDCardFileType[IDCardPartOfHuman]; !ok {
		errStr += "缺少身份证人像面\n"
	}
	if _, ok := UploadIDCardFileType[IDCardPartOfHuman]; !ok {
		errStr += "缺少身份证国徽面\n"
	}
	if _, ok := UploadIDCardFileType[IDCardPartOfHuman]; !ok {
		errStr += "缺少身份证手持人像面\n"
	}
	if errStr != "" {
		return nil, errors.New(errStr)
	}
	return finalPath, nil
}
